package com.docx4j.sample;

import org.docx4j.Docx4J;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.model.datastorage.migration.VariablePrepare;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import static com.docx4j.util.DocxUtils.*;


/**
 * docx4j word转pdf
 * https://www.iteye.com/blog/01jiangwei01-2124289
 * <p>
 * docx4j中模板的使用
 * https://www.chendd.cn/information/viewInformation/other/256.a
 * <p>
 * Office pptx/xlsx/docx to PDF to in docx4j 8.2.3
 * https://www.docx4java.org/blog/2020/09/office-pptxxlsxdocx-to-pdf-to-in-docx4j-8-2-3/
 * <p>
 * Convert DOCX to PDF using DOCX4J Java Library
 * http://www.techwaregeeks.com/word-processing/convert-docx-to-pdf-using-docx4j-java-library/
 */

public class PdfSample {

    public final static String NO_APPROVE_DOCX = "noApprove.docx",
            SEAL_KEY = "${seal}",
            SEAL_BOOK_MARK = "盖章",
            SEAL_PNG = "seal.png",
            NO_APPROVE_PDF = "noApprove.pdf";


    public static void main(String[] args) throws Exception {

        int ran = new Random().nextInt(100);

        String dir = new File(PdfSample.class.getResource("/").getPath())
                .getParentFile()
                .getParentFile()
                .getCanonicalPath()
                + File.separator + "doc" + File.separator;
        String templetate_docx = dir + NO_APPROVE_DOCX,
                seal_png = dir + SEAL_PNG,
                output_doc = dir + "noApprove-test" + ran + ".docx",
                output_pdf = dir + NO_APPROVE_PDF,
                output_pdf2 = dir + "noApprove-test" + ran + ".pdf";

        System.out.println(new File(PdfSample.class.getResource("/").getPath()));
        System.out.println(dir);
        System.out.println(templetate_docx);
        System.out.println(output_pdf);

        //准备数据
        Map<String, String> variables = new HashMap<String, String>();
        variables.put("farmInfo.houseHoldName", "罗布");
        variables.put("requestTypeLabel", "特困救助");
        variables.put("reasonLabels", "十分富裕，全村希望");
        variables.put("appdate", "2021年4月17日");
        variables.put("now_date", "2021年4月23日");
        docx2Pdf(templetate_docx, output_doc, output_pdf, output_pdf2, seal_png, variables);
    }

    public static void docx2Pdf(String templetate_docx, String output_doc, String output_pdf, String output_pdf2, String seal_png, Map<String, String> variables) {
        OutputStream pdfOutput = null;
        StringBuilder message = new StringBuilder();
        message.append(templetate_docx)
                .append(" <-转换-> ")
                .append(output_pdf);
        try {
            //加载模板
            WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new java.io.File(templetate_docx));

            //进行数据合并
            MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();

            // 列表元素
//            listMainDocumentPart(documentPart, 0);

            // 替换原有浮动图片
//            replaceDrawingWithImage(wordMLPackage, documentPart, seal_png);


            //插入图片
//            /*
            replaceBookMarkWithImage(wordMLPackage, documentPart, new HashMap<String, String>() {
                {
                    put(SEAL_BOOK_MARK, seal_png);
                }
            });
//            */

//            writeImage(wordMLPackage, documentPart, SEAL_KEY, seal_png);

            //数据替换预处理，调用API包
            //在表格替换后调用这个方法
            VariablePrepare.prepare(wordMLPackage);
            documentPart.variableReplace(variables);

            //pdf准备工作
            // Windows:
            // String  字体类型
            System.out.println("............................. PhysicalFonts size : " + PhysicalFonts.getPhysicalFonts().size());
            // 字体1，初始化，拿到系统中所有字体
            PhysicalFonts.discoverPhysicalFonts();
            // 字体2，手动添加
//            PhysicalFonts.addPhysicalFont(new URL("file:/C:/Windows/Fonts/simsun.ttc"));
//            PhysicalFonts.addPhysicalFont(new URL("file:/C:/Windows/Fonts/STZHONGS.TTF"));
//            PhysicalFonts.addPhysicalFonts("宋体", new URL("file:/C:/Windows/Fonts/simsun.ttc"));
//            PhysicalFonts.addPhysicalFonts("华文中宋", new URL("file:/C:/Windows/Fonts/STZHONGS.TTF"));

            System.out.println("............................. PhysicalFonts size : " + PhysicalFonts.getPhysicalFonts().size());

            // Set up font mapper (optional)
            Mapper fontMapper = new IdentityPlusMapper();

//            System.out.println("............................. fontMapper size : " + fontMapper.size());
//            System.out.println("............................. 宋体 : " + PhysicalFonts.get("SimSun"));
            System.out.println("............................. 华文中宋 : " + PhysicalFonts.get("STZhongsong"));
//            fontMapper.put("宋体", PhysicalFonts.get("SimSun"));
            fontMapper.put("华文中宋", PhysicalFonts.get("STZhongsong"));
//            System.out.println("............................. fontMapper size : " + fontMapper.size());
            wordMLPackage.setFontMapper(fontMapper);
            // FO exporter setup (required)
            // .. the FOSettings object
            FOSettings foSettings = Docx4J.createFOSettings();
//        foSettings.setFoDumpFile(new java.io.File(templetate_docx + ".fo"));
            foSettings.setWmlPackage(wordMLPackage);
            pdfOutput = new FileOutputStream(output_pdf);
//        Docx4J.toFO(foSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);
            Docx4J.save(wordMLPackage, new File(output_doc));
            Docx4J.toPDF(wordMLPackage, pdfOutput);
            pdfOutput.close();

            // 以输出文件为原文件再转pdf
            pdfOutput = new FileOutputStream(output_pdf2);
            wordMLPackage = WordprocessingMLPackage.load(new java.io.File(output_doc));
            Docx4J.toPDF(wordMLPackage, pdfOutput);
            pdfOutput.close();

            message.append("\n")
                    .append(output_doc)
                    .append(" <-转换-> ")
                    .append(output_pdf2);

            message.append("转换成功");
        } catch (Exception e) {
            message.append("转换失败");
            e.printStackTrace();
        } finally {
            try {
                pdfOutput.close();
            } catch (Exception e) {
            }
        }
        System.out.println(" docx to pdf : \n" + message);
    }


}
